use tokio::process::Command;
use tracing::{error, info};

/// 将 MP4 视频文件转换为 HLS (M3U8) 流媒体格式
///
/// 该函数使用 FFmpeg 将输入的 MP4 文件转换为 HLS 流媒体格式，生成 .m3u8 播放列表文件
/// 和对应的 .ts 分片文件，适用于视频点播 (VOD) 场景。
///
/// # 参数
/// - `input`: 输入 MP4 文件的路径
/// - `output_path`: 输出 M3U8 文件的路径（通常以 .m3u8 结尾）
/// - `segment_time`: 每个 TS 分片的时长（单位：秒）
/// - `ffmpeg_thread_count`: FFmpeg 使用的线程数量
///
/// # 返回值
/// 返回 `bool` 类型：
/// - `true`: 转换成功
/// - `false`: 转换失败
///
/// # 功能特性
/// - 使用 libx264 视频编码器
/// - 使用 AAC 音频编码器  
/// - 生成 VOD 类型的 HLS 播放列表
/// - 支持多线程处理
/// - 详细的日志输出
///
/// # 注意事项
/// - 需要系统中已安装 FFmpeg
/// - 输出目录必须存在且有写入权限
/// - 建议 segment_time 在 2-10 秒之间
///
/// # 示例
/// ```
/// use common_service::ffmpeg_helper::mp4_to_m3u8;
///
/// # tokio_test::block_on(async {
/// let success = mp4_to_m3u8("ffmpeg","input.mp4", "output/video.m3u8", 6, 4).await;
/// if success {
///     println!("转换成功！");
/// } else {
///     println!("转换失败！");
/// }
/// # })
/// ```
///
/// # 错误处理
/// 函数会记录详细的错误信息到日志中，包括：
/// - Ffmpeg 进程启动失败
/// - Ffmpeg 执行错误和 stderr 输出
pub async fn mp4_to_m3u8(
    filename: &str,
    input: &str,
    output_path: &str,
    segment_time: i8,
    ffmpeg_thread_count: i8,
) -> bool {
    info!("开始转换: {} -> {}", input, output_path);

    let result = Command::new(filename)
        .args([
            "-threads",
            &ffmpeg_thread_count.to_string(),
            "-i",
            input,
            "-c:v",
            "libx264", // H.264 视频编码，广泛兼容
            "-c:a",
            "aac", // AAC 音频编码，HLS 标准要求
            "-f",
            "hls", // 输出格式为 HLS
            "-hls_time",
            &segment_time.to_string(), // 分片时长
            "-hls_playlist_type",
            "vod", // 点播模式，生成完整播放列表
            &output_path,
        ])
        .output()
        .await;

    match result {
        Ok(output) => {
            if output.status.success() {
                info!("✅ 转换成功: {}", output_path);
                true
            } else {
                let stderr = String::from_utf8_lossy(&output.stderr);
                error!("❌ 转换失败: {}\n原因:\n{}", input, stderr);
                false
            }
        }
        Err(e) => {
            error!("❌ 无法启动 ffmpeg 进程: {}\n错误信息: {:?}", input, e);
            false
        }
    }
}
